package com.kawa.kemanage.util;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisUtil {
    private static JedisPool jedisPool = null;

    static {
        // 初始化连接池
        JedisPoolConfig config = new JedisPoolConfig();
        // 最大连接数
        config.setMaxTotal(100);
        // 最大空闲连接数
        config.setMaxIdle(10);
        // 获取连接时的最大等待毫秒数
        config.setMaxWaitMillis(1000);
        // 在获取连接的时候检查有效性
        config.setTestOnBorrow(true);

        // 创建连接池
        jedisPool = new JedisPool(config, "localhost", 6379);
    }

    /**
     * 获取Jedis实例
     */
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * 释放Jedis资源
     */
    public static void close(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }

    // ============================== String ==============================

    /**
     * 设置键值对
     */
    public static String set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.set(key, value);
        } finally {
            close(jedis);
        }
    }

    /**
     * 设置键值对并设置过期时间
     */
    public static String setex(String key, int seconds, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.setex(key, seconds, value);
        } finally {
            close(jedis);
        }
    }

    /**
     * 获取键对应的值
     */
    public static String get(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.get(key);
        } finally {
            close(jedis);
        }
    }

    /**
     * 删除键
     */
    public static Long del(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.del(key);
        } finally {
            close(jedis);
        }
    }

    /**
     * 设置键的过期时间
     */
    public static Long expire(String key, int seconds) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.expire(key, seconds);
        } finally {
            close(jedis);
        }
    }

    /**
     * 判断键是否存在
     */
    public static Boolean exists(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.exists(key);
        } finally {
            close(jedis);
        }
    }

    // ============================== Hash ==============================

    /**
     * 设置哈希字段值
     */
    public static Long hset(String key, String field, String value) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hset(key, field, value);
        } finally {
            close(jedis);
        }
    }

    /**
     * 获取哈希字段值
     */
    public static String hget(String key, String field) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hget(key, field);
        } finally {
            close(jedis);
        }
    }

    /**
     * 获取哈希所有字段和值
     */
    public static Map<String, String> hgetAll(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.hgetAll(key);
        } finally {
            close(jedis);
        }
    }

    // ============================== List ==============================

    /**
     * 从列表左侧插入元素
     */
    public static Long lpush(String key, String... values) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lpush(key, values);
        } finally {
            close(jedis);
        }
    }

    /**
     * 从列表右侧插入元素
     */
    public static Long rpush(String key, String... values) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.rpush(key, values);
        } finally {
            close(jedis);
        }
    }

    /**
     * 获取列表指定范围内的元素
     */
    public static List<String> lrange(String key, long start, long end) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.lrange(key, start, end);
        } finally {
            close(jedis);
        }
    }

    // ============================== Set ==============================

    /**
     * 向集合添加元素
     */
    public static Long sadd(String key, String... members) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.sadd(key, members);
        } finally {
            close(jedis);
        }
    }

    /**
     * 获取集合所有成员
     */
    public static Set<String> smembers(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.smembers(key);
        } finally {
            close(jedis);
        }
    }

    // ============================== ZSet ==============================

    /**
     * 向有序集合添加成员
     */
    public static Long zadd(String key, double score, String member) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.zadd(key, score, member);
        } finally {
            close(jedis);
        }
    }

    /**
     * 获取有序集合指定范围内的成员
     */
    public static Set<String> zrange(String key, long start, long end) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return (Set<String>) jedis.zrange(key, start, end);
        } finally {
            close(jedis);
        }
    }

    // ============================== 其他 ==============================

    /**
     * 获取键的剩余生存时间
     */
    public static Long ttl(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.ttl(key);
        } finally {
            close(jedis);
        }
    }

    /**
     * 原子递增
     */
    public static Long incr(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.incr(key);
        } finally {
            close(jedis);
        }
    }

    /**
     * 原子递减
     */
    public static Long decr(String key) {
        Jedis jedis = null;
        try {
            jedis = getJedis();
            return jedis.decr(key);
        } finally {
            close(jedis);
        }
    }
}
